---
title: React Hook Form
description: Learn how to integrate Emblor with React Hook Form.
---

In this guide, we will take a look at integrating Emblor with [React Hook Form](https://react-hook-form.com/), a popular form library for React applications. React Hook Form is a lightweight and performant library that allows you to build forms with ease. By integrating Emblor with React Hook Form, you can create a fully-featured tag input component that is highly customizable and accessible.

<Tabs defaultValue="preview" className="relative mr-auto w-full">
  <div className="flex items-center justify-between pb-3">
    <TabsList className="w-full justify-start rounded-none border-b bg-transparent p-0">
      <TabsTrigger
        value="preview"
        className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
      >
        Preview
      </TabsTrigger>
      <TabsTrigger
        value="code"
        className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
      >
        Code
      </TabsTrigger>
    </TabsList>
  </div>
  <TabsContent value="preview" className="relative rounded-md border">
    <ShadcnFormDemo />
  </TabsContent>
  <TabsContent value="code">
    <div className="flex flex-col space-y-4">
      <div className="w-full rounded-md [&_pre]:my-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
      <CodeBlock value={`
    import { z } from 'zod';
    import { useForm } from 'react-hook-form';
    import React from 'react';
    import { toast } from '@/components/ui/use-toast';
    import { Tag, TagInput } from 'emblor';

    const FormSchema = z.object({
      topics: z.array(
        z.object({
          id: z.string(),
          text: z.string(),
        }),
      ),
    });

    const defaultTags: Tag[] = [
      { id: uuid(), text: 'Sports' },
      { id: uuid(), text: 'Programming' },
      { id: uuid(), text: 'Travel' },
      { id: uuid(), text: 'Music' },
      { id: uuid(), text: 'Food' },
    ];

    export function ReactHookFormDemo() {
      const [tags, setTags] = React.useState<Tag[]>(defaultTags);
      const [activeTagIndex, setActiveTagIndex] = React.useState<number | null>(null);
      const { control, handleSubmit, setValue } = useForm();

      function onSubmit(data: any) {
        toast({
          title: 'You submitted the following values:',
          description: (
            <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
              <code className="text-white">{JSON.stringify(data, null, 2)}</code>
            </pre>
          ),
        });
      }

      return (
        <section className="z-10 w-full flex flex-col items-center text-center gap-5">
          <div id="try" className="w-full py-8">
            <div className="w-full relative my-4 flex flex-col space-y-2">
              <div className="preview flex min-h-[350px] w-full justify-center p-10 items-center mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 relative rounded-md">
                <form onSubmit={handleSubmit(onSubmit)}>
                  <Controller
                    name="tags"
                    control={control}
                    render={({ field }) => (
                      <TagInput
                        {...field}
                        placeholder="Enter a topic"
                        tags={tags}
                        className="max-w-[250px]"
                        setTags={(newTags) => {
                          setTags(newTags);
                          setValue('topics', newTags as [Tag, ...Tag[]]);
                        }}
                        activeTagIndex={activeTagIndex}
                        setActiveTagIndex={setActiveTagIndex}
                      />
                    )}
                  />
                  <button type="submit">Submit</button>
                </form>
              </div>
            </div>
          </div>
        </section>
      );

}
`}/>

</div>
</div>

  </TabsContent>
</Tabs>

## Installation

First, install Emblor and React Hook Form by running the following command:

<br />

```bash
npm install emblor react-hook-form
# Or, use any package manager of your choice.
```

## Integration with React-Hook-Form

Integrating Emblor with react-hook-form allows for easy form validation, submission, and more complex forms management. Here's how to integrate effectively:

### Basic integration

<br />

```tsx
import { useForm, Controller } from 'react-hook-form';
import { Tag, TagInput } from 'emblor';

function TagForm() {
  const { control, handleSubmit, setValue } = useForm();
  const [tags, setTags] = React.useState<Tag[]>([]);

  const onSubmit = (data) => {
    console.log(data.tags); // Process tag data
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="tags"
        control={control}
        render={({ field }) => (
          <TagInput
            {...field}
            placeholder="Enter a topic"
            tags={tags}
            className="sm:min-w-[450px]"
            setTags={(newTags) => {
              setTags(newTags);
              setValue('topics', newTags as [Tag, ...Tag[]]);
            }}
          />
        )}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

export default TagForm;
```

Overall the integration is straightforward. We use the Controller component from react-hook-form to manage the input field. The Controller component takes a name prop, which is the name of the field in the form data. The render prop is a function that returns the input component. In this case, we return the TagInput component from Emblor.
